﻿using System;
using System.Collections.Generic;
using OneDayModel.Interfaces;
using OneDayModel.Model;
using OneDayModel.Model.Repository;

namespace OneDayModel.Web
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            Application[typeof (IRepository).Name] = new HardCodedRepository();
        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }

    internal class HardCodedRepository : IRepository
    {
        private Dictionary<string, IUser> users = new Dictionary<string, IUser>();
        private Dictionary<string, string> confirmations = new Dictionary<string, string>();

        #region IRepository Members

        public IList<IRole> GetRoles()
        {
            return new List<IRole>(new Role[]
                                      {
                                          new Role("Basic", false, "", new List<IRoleAttribute>(
                                                                           new RoleAttribute[]
                                                                               {
                                                                                   new RoleAttribute("Alias", "Login", true, true,
                                                                                                     typeof (string), null),
                                                                                   new RoleAttribute("Password", "Password", true, true,
                                                                                                     typeof (string), null),
                                                                                   new RoleAttribute("eMail", "e-Mail", true, true,
                                                                                                     typeof (string), null)
                                                                               })),
                                          new Role("Model", true, "Basic", new List<IRoleAttribute>(
                                                                           new RoleAttribute[]
                                                                               {
                                                                                   new RoleAttribute("Heigh", "Heigh", true, true,
                                                                                                     typeof (string), null),
                                                                                   new RoleAttribute("ShoeSize", "Shoe Size", true, true,
                                                                                                     typeof (string), null),
                                                                                   new RoleAttribute("Weight", "Weight", true, true,
                                                                                                     typeof (string), null),
                                                                                   new RoleAttribute("EyeColor", "Eye Color", false, true,
                                                                                                     typeof (string), null)
                                                                               })),
                                         new Role("Photographer", true, "Basic", new List<IRoleAttribute>(
                                                                           new RoleAttribute[]
                                                                               {
                                                                                   new RoleAttribute("Camera Type", "CameraType", false, true,
                                                                                                     typeof (string), null)
                                                                                   
                                                                               })),
                                      });
            
        }

        public IUser NewUser()
        {
            return new HardCodedUser();
        }

        public bool IsAliasUnique(string alias)
        {
            return users.ContainsKey(alias);
        }

        public IUser GetUserByEmail(string email)
        {
            foreach (KeyValuePair<string, IUser> pair in users)
            {
                if (pair.Value["eMail"] == email)
                    return pair.Value;
            }
            return null;
        }

        public void CreateUser(string alias, string email, string password, IEnumerable<IRole> assignedRoles,
                               IEnumerable<KeyValuePair<string, string>> attributes, AccountStatus userAccountStatus)
        {
            users.Add(alias, new HardCodedUser(alias, email, password, assignedRoles));
        }

        public void RegisterConfirmationSent(string alias, string confirmationId)
        {
            confirmations.Add(alias, confirmationId);
        }

        public IUser GetUserPendingForConfirmation(string confirmationId)
        {
            throw new NotImplementedException();
        }

        public void UpdateUser(string alias, List<KeyValuePair<string, string>> changes)
        {
            IUser user = users[alias];
            foreach (KeyValuePair<string, string> change in changes)
            {
                user[change.Key] = change.Value;
            }
        }

        public void RegisterConfirmationDone(string confirmationId)
        {
            throw new NotImplementedException();
        }

        public IUser GetUserByAlias(string alias)
        {
            if (users.ContainsKey(alias))
                return users[alias];

            return null;
        }

        public StatisticsStruct CollectStatistics()
        {
            throw new NotImplementedException();
        }

        public IDictionary<string, IRoleAttribute> AllAttributesDefinitions
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }

    internal class HardCodedUser : IUser
    {
        private readonly List<IRole> roles = new List<IRole>();
        private AccountStatus accountStatus;
        private readonly Dictionary<string, IAttributeRecord> attributes = new Dictionary<string, IAttributeRecord>();

        public HardCodedUser(string alias, string email, string password, IEnumerable<IRole> roles)
        {
            this.roles.AddRange(roles);

            attributes.Add("Alias", new AttributeRecord(new RoleAttribute("Alias", "Alias", true, true, typeof(System.String), null)));
            attributes["Alias"].Value = alias;

            attributes.Add("eMail", new AttributeRecord(new RoleAttribute("eMail", "eMail", true, true, typeof(System.String), null)));
            attributes["eMail"].Value = alias;

            attributes.Add("Password", new AttributeRecord(new RoleAttribute("Password", "Password", true, true, typeof(System.String), null)));
            attributes["Password"].Value = alias;

            attributes.Add("AccountStatus", new AttributeRecord(new RoleAttribute("AccountStatus", "AccountStatus", true, false, typeof(System.String), null)));
            attributes["AccountStatus"].Value = AccountStatus.notExist.ToString();

            accountStatus = AccountStatus.notExist;
        }

        public HardCodedUser()
        {
            attributes.Add("AccountStatus", new AttributeRecord(new RoleAttribute("AccountStatus", "AccountStatus", true, false, typeof(System.String), null)));
            attributes["AccountStatus"].Value = AccountStatus.notExist.ToString();

            accountStatus = AccountStatus.notExist;
        }

        #region IUser Members

        public void AssignRole(IRole role)
        {
            roles.Add(role);
        }

        public void SetAttributes(IAttributeRecord[] attributes)
        {
            foreach (IAttributeRecord attributeRecord in attributes)
            {
                if (this.attributes.ContainsKey(attributeRecord.RoleAttribute.Name))
                    this.attributes[attributeRecord.RoleAttribute.Name] = attributeRecord;

                else
                    this.attributes.Add(attributeRecord.RoleAttribute.Name, attributeRecord);
            }
        }

        public void Create()
        {
            
        }

        public string this[string attributeName]
        {
            get { return attributes[attributeName].Value; }
            set
            {
                attributes[attributeName].Value = value;
            }
        }

        public void SetUserAccountStatus(AccountStatus accountStatus)
        {
            this.accountStatus = accountStatus;
        }

        public void CommitChanges()
        {
            
        }

        public IList<IRole> Roles
        {
            get { throw new NotImplementedException(); }
        }

        public IEnumerable<KeyValuePair<string, string>> AttributesRecords
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }
}